package com.xiaode.controller.app.student.binding;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaode.common.constant.Const;
import com.xiaode.common.model.*;
import com.xiaode.common.model.dto.notice.PairNoticeDTO;
import com.xiaode.exce.EnumError;
import com.xiaode.util.ChatUtil;

import java.sql.Connection;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class BindTeacherService {
    /**
     * 根据学生信息查询绑定老师信息
     *
     * @param studentId 学生id
     * @return
     */
    public Ret findBindTeacher(Integer studentId) throws Exception {
        Cache redis = Redis.use();
        //查询该师生关系状态为审核/通过的教师
        TeacherStudent teacherStudent = TeacherStudent.dao.findFirst("SELECT * FROM teacher_student WHERE studentId = ? AND state != 3", studentId);
        //查询绑定记录
        List<Record> recordList = Db.find("SELECT tsl.*,ad.name  FROM ts_log tsl INNER JOIN admin ad ON tsl.teacherId = ad.id WHERE tsl.studentId = ? ORDER BY id DESC", studentId);
        //判断是否已经绑定过老师
        if (BeanUtil.isNotEmpty(teacherStudent)) {
            //根据师生关系查询教师信息
            Admin admin = redis.get(Const.user.Admin + teacherStudent.getTeacherId());
            if (BeanUtil.isEmpty(admin) || admin.getIsDele()) {
                //删除之前师生关系
                TeacherStudent.dao.deleteById(teacherStudent.getId());
                return Ret.ok("teacher", null);
            }
            //查询绑定记录
            return Ret.ok("teacher", admin).set("bindState", teacherStudent.getState()).set("bindLog", recordList);
        }
        return Ret.ok("teacher", null).set("bindLog", recordList);
    }

    /**
     * 查询教师列表
     *
     * @return
     */
    public Ret findTeachers(String keyWord, Integer curPage, Integer pageSize) throws Exception {
        //查询教师列表
        Kv kv = Kv.create().setIfNotBlank("keyWord", keyWord);
        Page<Admin> teachers = Admin.dao.template("findTeachers", kv).paginate(curPage, pageSize);
        return Ret.ok("teachers", teachers);
    }

    /**
     * 绑定师生关系
     *
     * @param stuId     学生id
     * @param teacherId 教师id
     * @return
     */
    public Ret stuBindTeacher(Integer stuId, Integer teacherId) throws Exception {
        Cache redis = Redis.use();
        Student stu = redis.get(Const.user.Student + stuId);
        //查询当前教师是否存在
        Admin tea = redis.get(Const.user.Admin + teacherId);
        if (BeanUtil.isEmpty(tea) || tea.getUserType() == 0) {
            return Ret.fail().set("error", EnumError.TEACHER_NOT_EXIST.getObj());
        }
        //如果又多个通过的绑定,则删除全部 重新申请
        List<TeacherStudent> studentList = TeacherStudent.dao.find("SELECT * FROM teacher_student WHERE studentId = ? and state = 2", stuId);
        if (ObjectUtil.isAllNotEmpty(studentList)) {
            if (studentList.size() > 1) {
                Db.delete("delete from teacher_student where studentId = ? and state = 2", stuId);
            } else if (studentList.size() == 1) {
                //已经绑定过教师
                return Ret.fail().set("error", EnumError.BIND_TEACHER_FAIL.getObj());
            }
        }

        //给教师发送通知
        PairNoticeDTO noticeDTO = new PairNoticeDTO();
        Student o = redis.get(Const.user.Student + stuId);
        noticeDTO.setName(o.getName());
        noticeDTO.setSex(o.getSex());
        noticeDTO.setPic(o.getAvatarUrl());
        noticeDTO.setAccountId(stu.getAccountId());
        noticeDTO.setId(stuId);
        noticeDTO.setType(4);
        noticeDTO.setPairType(1);
        String s = JSONUtil.toJsonStr(noticeDTO);
        ArrayList<Integer> list = new ArrayList<>();
        Admin o1 = redis.get(Const.user.Admin + teacherId);
        list.add(o1.getAccountId());
        //发送消息通知
        //查询该师生绑定关系是否存在
        TeacherStudent relStuTea = TeacherStudent.dao.findFirst("SELECT * FROM teacher_student WHERE studentId = ? AND teacherId = ?", stuId, teacherId);
        TeacherStudentLog teacherStudentLog = new TeacherStudentLog();
        TsLog tsLog = new TsLog();
        tsLog.setType(1);
        tsLog.setState(1);
        tsLog.setStudentId(stuId);
        tsLog.setTeacherId(teacherId);
        if (BeanUtil.isEmpty(relStuTea)) {
            TeacherStudent nts = new TeacherStudent();
            nts.setTeacherId(teacherId);
            nts.setStudentId(stuId);
            nts.setState(1);
            nts.setAddTime(LocalDateTime.now());
            teacherStudentLog.setStudentId(stuId);
            teacherStudentLog.setTeacherId(teacherId);
            teacherStudentLog.setState(1);
            teacherStudentLog.setType(1);
            teacherStudentLog.setAddTime(LocalDateTime.now());
            teacherStudentLog.setUpdateTime(LocalDateTime.now());
            //事务内保存
            Db.tx(Connection.TRANSACTION_REPEATABLE_READ, () -> {
                try {
                    nts.save();
                    teacherStudentLog.save();
                    tsLog.setTeacherStudentLogId(teacherStudentLog.getId());
                    tsLog.save();
                } catch (Exception e) {
                    return false;
                }
                return true;
            });

            try {
                ChatUtil.sendNotice(s, 1, list);
            } catch (Exception e) {

            }
            return Ret.ok();
        }
        //如果relStuTea 不为空, 该学生已经绑定该教师,或者正在审核过程中
        if (relStuTea.getState() == 2 || relStuTea.getState() == 1) {
            return Ret.fail().set("error", EnumError.BIND_TEACHER_FAIL.getObj());
        }
        if (relStuTea.getState() == 3) {
            relStuTea.setTeacherId(teacherId);
            relStuTea.setAddTime(LocalDateTime.now());
            relStuTea.setState(1);
            teacherStudentLog.setStudentId(stuId);
            teacherStudentLog.setTeacherId(teacherId);
            teacherStudentLog.setState(1);
            teacherStudentLog.setType(1);
            teacherStudentLog.setAddTime(LocalDateTime.now());
            teacherStudentLog.setUpdateTime(LocalDateTime.now());
            Db.tx(Connection.TRANSACTION_REPEATABLE_READ, () -> {
                try {
                    relStuTea.update();
                    teacherStudentLog.save();
                    tsLog.setTeacherStudentLogId(teacherStudentLog.getId());
                    tsLog.save();
                } catch (Exception e) {
                    return false;
                }
                return true;
            });

            try {
                ChatUtil.sendNotice(s, 1, list);
            } catch (Exception e) {
            }
            return Ret.ok();
        }

        return Ret.fail().set("error", EnumError.USER_BIND_FAIL.getObj());
    }

    /**
     * 学生取消绑定教师申请
     *
     * @param stuId     学生id
     * @param teacherId 教师Id
     * @return
     */
    public Ret stuCancelBindTea(Integer stuId, Integer teacherId) throws Exception {
        Ret ret = Ret.create();
        Db.tx(Connection.TRANSACTION_REPEATABLE_READ,()->{
            try{
            //查询当前学生是否绑定该教师
            TeacherStudent teacherStudent = TeacherStudent.dao.findFirst("select * from teacher_student where studentId = ? and teacherId = ? AND state = 2", stuId, teacherId);
            //如果teacherStudent为null,该学生并未绑定该教师/并未提交绑定该教师的申请
            if (BeanUtil.isEmpty(teacherStudent)) {
                 ret.setFail().set("error", EnumError.NOT_PAIR.getObj());
                return false;
            }
            TeacherStudentLog first = TeacherStudentLog.dao.findFirst("SELECT * FROM teacher_student_log WHERE teacherId = ? AND studentId = ? AND state = 1", teacherId, stuId);
            if (BeanUtil.isNotEmpty(first)) {
                ret.setFail().set("error", EnumError.HAVE_APPLY_CANCEL_PAIR.getObj());
                return false;
            }
            //添加学生解除绑定log
            TeacherStudentLog teacherStudentLog = new TeacherStudentLog();
            teacherStudentLog.setAddTime(LocalDateTime.now());
            teacherStudentLog.setUpdateTime(LocalDateTime.now());
            teacherStudentLog.setStudentId(stuId);
            teacherStudentLog.setTeacherId(teacherId);
            teacherStudentLog.setType(2);
            teacherStudentLog.setState(1);

            TsLog tsLog = new TsLog();
            tsLog.setType(2);
            tsLog.setState(1);
            tsLog.setStudentId(stuId);
            tsLog.setTeacherId(teacherId);

            teacherStudentLog.save();
            tsLog.setTeacherStudentLogId(teacherStudentLog.getId());
            tsLog.save();
            ret.setOk();
            return true;
            }catch (Exception e){
                ret.setFail().set("error",EnumError.USER_BIND_FAIL.getObj());
                return false;
            }
        });

        //如果添加失败,则直接返回
        if (ret.isFail()){
            return ret;
        }
        //发送取消绑定的通知
        PairNoticeDTO noticeDTO = new PairNoticeDTO();
        Cache redis = Redis.use();
        Student o = redis.get(Const.user.Student + stuId);
        noticeDTO.setId(o.getId());
        noticeDTO.setSex(o.getSex());
        noticeDTO.setPic(o.getAvatarUrl());
        noticeDTO.setName(o.getName());
        noticeDTO.setAccountId(o.getAccountId());
        noticeDTO.setType(4);
        noticeDTO.setPairType(2);
        ArrayList<Integer> arrayList = new ArrayList<>();
        Admin ad = redis.get(Const.user.Admin + teacherId);
        arrayList.add(ad.getAccountId());
        ChatUtil.sendNotice(JSONUtil.toJsonStr(noticeDTO), 1, arrayList);

        return Ret.ok();
    }

}
